<template>
  <div class="chart-container">
    <div class="chart-header">
      <h3 class="chart-title">{{ chartTitle }}</h3>
      <el-select 
        v-model="selectedSeries" 
        @change="updateLegend" 
        class="series-selector"
        size="small"
      >
        <el-option value="All">
          <span class="option-label">全部接口</span>
        </el-option>
        <el-option 
          v-for="(data, index) in seriesData" 
          :key="index" 
          :value="data.name"
        >
          <span class="option-label">{{ data.name }}</span>
        </el-option>
      </el-select>
    </div>
    <div ref="chart" :style="{ width: chartWidth, height: chartHeight }"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'ResponseTimeChart',
  props: {
    chartTitle: {
      type: String,
      default: '平均响应时间'
    },
    chartUnit: {
      type: String,
      default: '单位(毫秒)'
    },
    chartWidth: {
      type: String,
      default: '400px'
    },
    chartHeight: {
      type: String,
      default: '300px'
    },
    xData: {
      type: Array,
      required: true
    },
    seriesData: {
      type: Array,
      required: true
    },
    // 添加图表类型属性，用于区分不同类型的图表
    chartType: {
      type: String,
      default: 'responseTime' // 可选值: responseTime, rps, tps, users, p90, p99
    }
  },
  data() {
    return {
      selectedSeries: 'All', // 默认选择全部
    };
  },

  mounted() {
    this.$nextTick(() => {
      this.initChart();
    });
  },

  watch: {
    // 监听数据变化，自动更新图表
    xData: {
      handler() {
        this.$nextTick(() => {
          this.updateChart();
        });
      },
      deep: true
    },
    seriesData: {
      handler() {
        this.$nextTick(() => {
          this.updateChart();
        });
      },
      deep: true
    }
  },

  methods: {
    initChart() {
      if (!this.$refs.chart) return;
      
      const chart = echarts.init(this.$refs.chart);
      this.chartInstance = chart; // 保存实例以便后续更新
      
      // 监听窗口大小变化
      window.addEventListener('resize', () => {
        chart.resize();
      });
      
      this.updateChart(); // 初始化图表
    },

    updateLegend() {
      this.updateChart(); // 更新图表
    },

    updateChart() {
      if (!this.chartInstance) return;
      
      const chart = this.chartInstance;

      // 检查数据是否存在
      if (!this.xData || !this.seriesData || this.seriesData.length === 0) {
        console.log('图表数据为空，跳过更新');
        return;
      }

      // 根据图表类型获取样式配置
      const styleConfig = this.getChartStyleConfig();

      const series = this.seriesData.map((data, index) => ({
        name: data.name,
        type: 'line',
        data: this.selectedSeries === 'All' || this.selectedSeries === data.name ? data.values : [],
        showSymbol: styleConfig.showSymbol,
        symbolSize: styleConfig.symbolSize,
        smooth: styleConfig.smooth,
        lineStyle: {
          width: styleConfig.lineWidth,
          type: this.getLineType(index, styleConfig),
          shadowColor: 'rgba(0, 0, 0, 0.3)',
          shadowBlur: styleConfig.shadowBlur,
          shadowOffsetY: 1,
          cap: 'round'
        },
        itemStyle: {
          color: this.getSeriesColor(index, styleConfig),
          borderWidth: 2,
          borderColor: this.getSeriesColor(index, styleConfig),
          shadowColor: 'rgba(0, 0, 0, 0.3)',
          shadowBlur: 2
        },
        areaStyle: this.getAreaStyle(index, styleConfig),
        emphasis: {
          focus: 'series',
          lineStyle: {
            width: styleConfig.lineWidth + 1,
            shadowBlur: styleConfig.shadowBlur + 2
          },
          itemStyle: {
            borderWidth: 3,
            shadowBlur: 4
          }
        }
      }));

      const option = {
        color: styleConfig.colors,
        tooltip: {
          trigger: 'axis',
          formatter: (params) => {
            let result = `<div style="font-weight: bold; margin-bottom: 5px;">${params[0].axisValue}</div>`;
            params.forEach(param => {
              if (param.data !== undefined) {
                result += `
                  <div style="display: flex; align-items: center; margin: 3px 0;">
                    <span style="display: inline-block; width: 10px; height: 10px; 
                      background-color: ${param.color}; border-radius: 50%; margin-right: 5px;">
                    </span>
                    <span>${param.seriesName}: ${param.data} ${this.chartUnit}</span>
                  </div>`;
              }
            });
            return result;
          },
          backgroundColor: 'rgba(255, 255, 255, 0.95)',
          borderColor: '#ddd',
          borderWidth: 1,
          textStyle: {
            color: '#333',
            fontSize: 12
          },
          extraCssText: 'box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); border-radius: 4px;'
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '10%',
          top: '5%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: this.xData,
          axisLabel: {
            rotate: 45,
            color: '#666',
            fontSize: 11,
            interval: 'auto'
          },
          axisLine: {
            lineStyle: {
              color: '#e8e8e8',
              width: 1
            }
          },
          axisTick: {
            show: false
          }
        },
        yAxis: {
          name: this.chartUnit,
          nameLocation: 'middle',
          nameGap: 40,
          nameTextStyle: {
            color: '#666',
            fontSize: 12
          },
          type: 'value',
          axisLabel: {
            color: '#666',
            fontSize: 11,
            formatter: (value) => {
              if (value >= 1000) {
                return (value / 1000).toFixed(1) + 'k';
              }
              return value;
            }
          },
          axisLine: {
            show: false
          },
          splitLine: {
            lineStyle: {
              color: '#f0f0f0',
              type: 'dashed'
            }
          }
        },
        series: series,
        legend: {
          show: this.selectedSeries === 'All' && series.length > 1,
          bottom: 0,
          data: series.map(s => s.name),
          textStyle: {
            fontSize: 11,
            color: '#666'
          },
          icon: styleConfig.legendIcon,
          itemWidth: 16,
          itemHeight: 10,
          itemGap: 10
        },
        animation: true,
        animationDuration: 500,
        animationEasing: 'cubicOut'
      };

      chart.setOption(option, true); // 第二个参数为true表示不合并选项
    },
    
    // 根据图表类型获取样式配置
    getChartStyleConfig() {
      const configs = {
        responseTime: {
          colors: [
            '#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', 
            '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc', '#ff9f7f'
          ],
          smooth: true,
          lineWidth: 3,
          showSymbol: false,
          symbolSize: 6,
          shadowBlur: 5,
          useGradient: true,
          legendIcon: 'roundRect',
          defaultLineType: 'solid',
          areaOpacity: 0.15
        },
        rps: {
          colors: [
            '#5b8ff9', '#61ddaa', '#f6bd16', '#7262fd', '#78d3f8',
            '#9661bc', '#f6903d', '#008685', '#f08bb4', '#65b581'
          ],
          smooth: true,
          lineWidth: 3,
          showSymbol: false,
          symbolSize: 6,
          shadowBlur: 4,
          useGradient: true,
          legendIcon: 'circle',
          defaultLineType: 'solid',
          areaOpacity: 0.2
        },
        tps: {
          colors: [
            '#ff6b3b', '#626c91', '#a0a7e6', '#c4ebad', '#96dee8',
            '#ff9d6c', '#bad6ff', '#bbe2bb', '#ffd0a9', '#d7baf9'
          ],
          smooth: true,
          lineWidth: 3,
          showSymbol: false,
          symbolSize: 6,
          shadowBlur: 3,
          useGradient: true,
          legendIcon: 'pin',
          defaultLineType: 'solid',
          areaOpacity: 0.15
        },
        users: {
          colors: [
            '#1890ff', '#2fc25b', '#facc14', '#223273', '#8543e0',
            '#13c2c2', '#3436c7', '#f04864', '#5cdbd3', '#6dc8ec'
          ],
          smooth: false,
          lineWidth: 4,
          showSymbol: true,
          symbolSize: 8,
          shadowBlur: 6,
          useGradient: true,
          legendIcon: 'rect',
          defaultLineType: 'solid',
          areaOpacity: 0.25
        },
        p90: {
          colors: [
            '#9b8bfe', '#26deca', '#f8c032', '#ff5722', '#07a2a4',
            '#4cc9f0', '#4361ee', '#7209b7', '#f72585', '#3a0ca3'
          ],
          smooth: true,
          lineWidth: 3,
          showSymbol: false,
          symbolSize: 6,
          shadowBlur: 4,
          useGradient: true,
          legendIcon: 'diamond',
          defaultLineType: 'dashed',
          areaOpacity: 0.1
        },
        p99: {
          colors: [
            '#e84a5f', '#2a9d8f', '#e9c46a', '#264653', '#f4a261',
            '#ff9f1c', '#2ec4b6', '#e71d36', '#011627', '#fdfffc'
          ],
          smooth: true,
          lineWidth: 3,
          showSymbol: false,
          symbolSize: 6,
          shadowBlur: 5,
          useGradient: true,
          legendIcon: 'triangle',
          defaultLineType: 'dotted',
          areaOpacity: 0.12
        }
      };
      
      // 如果没有对应的配置，使用默认配置
      return configs[this.chartType] || configs.responseTime;
    },
    
    // 获取线条类型
    getLineType(index, styleConfig) {
      const lineTypes = ['solid', 'dashed', 'dotted'];
      
      // 对于p90和p99图表，使用特定的线条类型
      if (this.chartType === 'p90' || this.chartType === 'p99') {
        return styleConfig.defaultLineType;
      }
      
      // 对于其他图表，轮换使用不同的线条类型
      return lineTypes[index % lineTypes.length];
    },
    
    // 获取系列颜色
    getSeriesColor(index, styleConfig) {
      return styleConfig.colors[index % styleConfig.colors.length];
    },
    
    // 获取区域样式
    getAreaStyle(index, styleConfig) {
      const color = this.getSeriesColor(index, styleConfig);
      
      // 如果不是单一系列或不使用渐变，则不显示区域
      if (this.selectedSeries === 'All' || !styleConfig.useGradient) {
        return null;
      }
      
      // 使用渐变色
      return {
        color: {
          type: 'linear',
          x: 0,
          y: 0,
          x2: 0,
          y2: 1,
          colorStops: [{
            offset: 0, 
            color: color + Math.floor(styleConfig.areaOpacity * 255).toString(16).padStart(2, '0') // 转换透明度为十六进制
          }, {
            offset: 1, 
            color: color + '00' // 完全透明
          }]
        },
        origin: 'auto'
      };
    },
    
    // 组件销毁时清理资源
    beforeDestroy() {
      if (this.chartInstance) {
        this.chartInstance.dispose();
      }
      window.removeEventListener('resize', this.resizeHandler);
    }
  }
};
</script>

<style scoped>
.chart-container {
  width: 100%;
  height: 100%;
}

.chart-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 15px;
  padding: 0 5px;
}

.chart-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  letter-spacing: 0.5px;
}

.series-selector {
  width: 150px;
  transition: all 0.3s ease;
}

.series-selector:hover {
  transform: translateY(-1px);
}

.series-selector :deep(.el-input__inner) {
  font-size: 12px;
  height: 30px;
  line-height: 30px;
  border-radius: 15px;
  border: 1px solid #e4e7ed;
  padding-left: 15px;
  transition: all 0.3s ease;
}

.series-selector :deep(.el-input__inner:hover),
.series-selector :deep(.el-input__inner:focus) {
  border-color: #5470c6;
  box-shadow: 0 0 0 2px rgba(84, 112, 198, 0.2);
}

.series-selector :deep(.el-input__suffix) {
  right: 8px;
}

.option-label {
  font-size: 12px;
  color: #606266;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 下拉菜单样式 */
:deep(.el-select-dropdown__item) {
  font-size: 12px;
  height: 30px;
  line-height: 30px;
}

:deep(.el-select-dropdown__item.selected) {
  color: #5470c6;
  font-weight: 600;
}

:deep(.el-select-dropdown__item.hover) {
  background-color: rgba(84, 112, 198, 0.1);
}

/* 自适应样式 */
@media (max-width: 768px) {
  .chart-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
  
  .series-selector {
    width: 100%;
  }
}
</style>
